<?php

namespace backend\controllers;


use common\models\User;
use common\rules\ParamsRule;
use Yii;
use yii\base\Action;
use yii\filters\AccessControl;
use yii\web\Controller;

class BaseController extends Controller
{
    /**
     * 当前菜单路由 设置false 使用当前action路由
     *
     * @var string
     */
    public $menuRoute;

    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'rules' => [
                    [
                        'allow' => true,
                        'roles' => ['@'],
                        'matchCallback' => array($this, 'checkRoutePermission'),
                    ]
                ],
                'except' => ['error'],
            ],
        ];
    }

    public function init()
    {
        parent::init();
        Yii::$app->get('option')->initUserSettings();
    }

    /**
     * @param $rule
     * @param Action $action
     * @return bool
     */
    public function checkRoutePermission($rule, $action)
    {
        $user = Yii::$app->getUser();
        if ($user->getId() == User::ROOT_ID) {
            return true;
        }

        return $this->canAccessByRoute($action->getUniqueId(),
            Yii::$app->getRequest()->getQueryParams());
    }

    /**
     * @param $userId
     * @return \yii\rbac\Permission[]
     */
    protected function getRoutePermissionsByUser($userId)
    {
        static $permissions;
        if (!isset($permissions)) {
            $permissions = Yii::$app->getAuthManager()->getPermissionsByUser($userId);
            foreach ($permissions as $name => $permission) {
                if (!preg_match('#^[A-z0-9_\-]+:#', $name)) {
                    unset($permissions[$name]);
                }
            }
        }
        return $permissions;
    }

    /**
     * 根据route是否可以访问
     * @param $route
     * @param array $params
     * @return bool
     */
    public function canAccessByRoute($route, $params = [])
    {
        $user = Yii::$app->getUser();
        $permissions = $this->getRoutePermissionsByUser($user->getId());
        $appId = Yii::$app->id;

        if ($route[0] !== '/') {
            $route = '/' . $route;
        }

        Yii::trace('Check Route' . $route);

        if (!isset($permissions[$appId . ':' . $route])) {
            while ($pos = strrpos($route, '/')) {
                $route = substr($route, 0, $pos);
                if (isset($permissions[$appId . ':' . $route])) {
                    $permission = $permissions[$appId . ':' . $route];
                    break;
                }
            }
        } else {
            $permission = $permissions[$appId . ':' . $route];
        }

        if (isset($permission)) {
            if ($permission->ruleName) {
                $rule = Yii::$app->getAuthManager()->getRule($permission->ruleName);
                if (!$rule || !$rule->execute($user->getId(), $permission, $params)) {
                    return false;
                }
            }
            return true;
        } else {
            return false;
        }
    }

}